﻿using System;
using System.Configuration;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Client.Properties;

namespace Client
{
    public partial class MainForm : Form
    {
        /// <summary>用于连接服务器的socket</summary>
        private Socket _socket;

        /// <summary>处理接收服务器端数据的线程</summary>
        private Thread _threadReceive;

        public MainForm()
        {
            InitializeComponent();
            string serverIp = ConfigurationManager.ConnectionStrings["serverIP"].ConnectionString;
            string serverPort = ConfigurationManager.ConnectionStrings["serverPort"].ConnectionString;
            StartClient(IPAddress.Parse(serverIp), int.Parse(serverPort));
            txtAddress.Text = serverIp;
            txtPort.Text = serverPort;
        }

        private void BtnSendMsgClick(object sender, EventArgs e)
        {
            string msg = txtSendMsg.Text;
            if (msg.Length == 0)
            {
                MessageBox.Show(Resources.MainForm_BtnSendMsgClick_);
                return;
            }
            SendToServer(msg);
        }

        /// <summary>
        /// 发送消息到服务器
        /// </summary>
        /// <param name="message">消息</param>
        private void SendToServer(string message)
        {
            try
            {
                _socket.Send(Encoding.UTF8.GetBytes(message));
                AddTalkMessage(string.Format("我说：{0}", message));
            }
            catch
            {
                AddTalkMessage("发送信息失败");
            }
        }

        private void MainFormFormClosing(object sender, FormClosingEventArgs e)
        {
            _socket.Close();
        }

        /// <summary>开启客户端</summary>
        public void StartClient(IPAddress ip, int port)
        {
            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                _socket.Connect(ip, port);
            }
            catch (Exception)
            {
                ChangeStatus(false);
                AddTalkMessage("服务器未开启！");
                return;
            }
            ChangeStatus(true);
            _threadReceive = new Thread(ReceiveData) { IsBackground = true };
            _threadReceive.Start();
        }

        /// <summary>处理接收的服务器端数据</summary>
        private void ReceiveData()
        {
            while (true)
            {
                var byteMessage = new byte[1024];
                int msgLength = 0;
                try
                {
                    //从网络流中读出字符串
                    //如果服务器异常退出，则会产生异常
                    msgLength = _socket.Receive(byteMessage);
                }
                catch
                {
                    AddTalkMessage("与服务器失去联系！");
                    ChangeStatus(false);
                    StopClient();
                }

                if (msgLength == 0)
                {
                    AddTalkMessage("与服务器失去联系！");
                    ChangeStatus(false);
                    StopClient();
                    return;
                }
                AddTalkMessage("[服务器]说：" + Encoding.UTF8.GetString(byteMessage, 0, msgLength));
            }
        }

        /// <summary>提示是否与服务器连接</summary>
        private void ChangeStatus(bool status)
        {
            if (labelStatus.InvokeRequired)
            {
                StatusDelegate d = ChangeStatus;
                labelStatus.Invoke(d, new object[] { status });
            }
            else
            {
                labelStatus.Text = status ? "Success connected..." : "Failure connected...";
            }
        }

        /// <summary> 在txtMsg中追加聊天信息</summary>
        private void AddTalkMessage(string message)
        {
            if (txtMsg.InvokeRequired)
            {
                MessageDelegate d = AddTalkMessage;
                txtMsg.Invoke(d, new object[] { message });
            }
            else
            {
                txtMsg.AppendText(message + Environment.NewLine);
                txtMsg.ScrollToCaret();
            }
        }

        /// <summary>关闭客户端</summary>
        private void StopClient()
        {
            //未与服务器连接前_socket为null
            if (_socket == null) return;
            _threadReceive.Abort();
            _socket.Shutdown(SocketShutdown.Both);
            _socket.Close();
        }

        #region Nested type: MessageDelegate

        private delegate void MessageDelegate(string message);

        #endregion

        #region Nested type: StatusDelegate

        private delegate void StatusDelegate(bool status);

        #endregion
    }
}